package com.clpms.service.impl;

import com.clpms.bean.enumBean.DataStatusEnum;
import com.clpms.bean.enumBean.ErrorCodeEnum;
import com.clpms.bean.req.AddWorkReq;
import com.clpms.bean.req.DeleteWorkReq;
import com.clpms.bean.req.QueryWorkReq;
import com.clpms.bean.req.UpdateWorkReq;
import com.clpms.bean.resp.LearnRecordForWorkResp;
import com.clpms.bean.resp.QueryWorkResp;
import com.clpms.dao.mapper.CourseDao;
import com.clpms.dao.mapper.LearnRecordDao;
import com.clpms.dao.mapper.WorkDao;
import com.clpms.dao.pojo.Course;
import com.clpms.dao.pojo.LearnRecord;
import com.clpms.dao.pojo.Work;
import com.clpms.service.WorkService;
import com.clpms.utils.CommonException;
import com.clpms.utils.CurrentUser;
import com.clpms.utils.UserUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author caixinyong
 * @date 2023/5/11 8:51 PM
 */

@Service
@Slf4j
public class WorkServiceImpl implements WorkService {
    @Resource
    private WorkDao workDao;
    @Resource
    private CourseDao courseDao;
    @Resource
    private LearnRecordDao learnRecordDao;

    @Override
    public PageInfo<QueryWorkResp> queryWork(QueryWorkReq req) {
        CurrentUser currentUser = UserUtils.get();
        PageHelper.startPage(req.getPageNum(), req.getPageSize());
        List<Work> workList =
                workDao.selectByKeyword(
                        req.getWorkType(), req.getCourseId(), currentUser.getSchoolId(), currentUser.getTeacherId(),
                        DataStatusEnum.NORMAL.getCode()
                );
        PageInfo<Work> workPageInfo = new PageInfo<>(workList);
        List<Work> workList1 = workPageInfo.getList();
        if (CollectionUtils.isEmpty(workList1)) {
            if (Objects.nonNull(req.getCourseId())) {
                throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "当前课程还未添加过作业");
            }
            if (Objects.nonNull(req.getWorkType())) {
                throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "当前类型还未添加过作业");
            }
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "您还未添加过作业");
        }
        List<Long> courseIdList = workList1.stream().map(Work::getCourseId).collect(Collectors.toList());
        List<Course> courseList = courseDao.querybyIdList(courseIdList);
        Map<Long, String> courseIdAndNameMap = courseList.stream().collect(Collectors.toMap(
                Course::getId,
                course -> String.format("%s [编号:%s]", course.getName(), course.getCourseNo()))
        );
        List<Long> workIdList = workList1.stream().map(Work::getId).collect(Collectors.toList());
        Map<Long, List<LearnRecordForWorkResp>> workAndLearnRecordMap = queryLearnRecordByWorkIdList(workIdList);
        List<QueryWorkResp> workRespList = workList1.stream()
                .map(work ->
                        QueryWorkResp.builder()
                                .id(work.getId())
                                .courseName(courseIdAndNameMap.get(work.getCourseId()))
                                .name(work.getName())
                                .workType(work.getWorkType())
                                .workNo(work.getWorkNo())
                                .remark(work.getRemark())
                                .learnRecordForWorkResp(workAndLearnRecordMap.get(work.getId()))
                                .learnOutcomeNumber(work.getLearnOutcomeNumber())
                                .build()
                ).collect(Collectors.toList());
        PageInfo<QueryWorkResp> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(workPageInfo.getPageNum());
        pageInfo.setSize(workPageInfo.getSize());
        pageInfo.setList(workRespList);
        return pageInfo;
    }

    @Override
    public Boolean addWork(AddWorkReq req) {
        CurrentUser currentUser = UserUtils.get();

        Long courseId = req.getCourseId();
        Course course = courseDao.selectById(courseId);
        if (Objects.isNull(course)) {
            throw new CommonException(ErrorCodeEnum.PARAM_ERROR.getCode(), "当前课程不存在");
        }
        Long workCount = workDao.selectCountByCourseIdNotStatus(courseId);
        workDao.insert(
                Work.builder()
                        .name(req.getName())
                        .workNo(String.format("%s-%s", course.getCourseNo(), workCount + 1))
                        .schoolId(currentUser.getSchoolId())
                        .teacherId(currentUser.getTeacherId())
                        .courseId(courseId)
                        .workType(req.getWorkType())
                        .remark(req.getRemark())
                        .build());

        return Boolean.TRUE;
    }

    @Override
    public Boolean deleteWork(DeleteWorkReq req) {
        CurrentUser currentUser = UserUtils.get();
        workDao.deleteById(req.getWorkId(), currentUser.getSchoolId(), currentUser.getTeacherId());
        learnRecordDao.deleteByWorkId(req.getWorkId(), currentUser.getSchoolId(), currentUser.getTeacherId());
        return Boolean.TRUE;
    }

    @Override
    public Boolean updateWork(UpdateWorkReq req) {
        CurrentUser currentUser = UserUtils.get();
        Work work = Work.builder()
                .id(req.getId())
                .name(req.getName())
                .workType(req.getWorkType())
                .remark(req.getRemark())
                .build();
        workDao.updateById(work);
        return Boolean.TRUE;
    }

    private Map<Long, List<LearnRecordForWorkResp>> queryLearnRecordByWorkIdList(List<Long> workIdList) {
        List<LearnRecord> learnRecords = learnRecordDao.selectByWorkIdList(workIdList, DataStatusEnum.NORMAL.getCode());
        List<LearnRecordForWorkResp> recordForWorkResps = learnRecords.stream()
                .map(learnRecord ->
                        LearnRecordForWorkResp.builder()
                                .id(learnRecord.getId())
                                .remark(learnRecord.getRemark())
                                .score(learnRecord.getScore())
                                .completionTime(learnRecord.getCompletionTime())
                                .easyType(learnRecord.getEasyType())
                                .progress(learnRecord.getProgress())
                                .workId(learnRecord.getWorkId())
                                .build())
                .collect(Collectors.toList());
        return recordForWorkResps.stream()
                .collect(
                        Collectors.groupingBy(LearnRecordForWorkResp::getWorkId)
                );
    }
}
